/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Aplicación;

/**
 *
 * @author MariaDeFreitas
 */
import Aplicación.Server.ClientThread;
import Grandulon.Election;
import Grandulon.RunningThread;
import java.io.*;
import java.net.*;
import java.util.ArrayList;

/*
 * Cliente
 */
public class Client  {

	// Para I/O
	private ObjectInputStream sInput;		// Para leer del socket
	private ObjectOutputStream sOutput;		// Para escribir en el socket
	private Socket socket;

	// if I use a GUI or not
	private ClientGUI cg;
	
	// El servidor el puerto y el nombre de usuario
	private String server, username;
	private int port;
        public static ArrayList<ClientThread> alist;
	/*
	 *  Constructor 
	 *  server: la ip del servidor
	 *  port: el numero de puerto
	 *  username: nombre de usuario
	 */
	Client(String server, int port, String username) {
		// which calls the common constructor with the GUI set to null
		this(server, port, username, null,null);
	}

	/*
	 * Constructor call when used from a GUI
	 * in console mode the ClienGUI parameter is null
	 */
	Client(String server, int port, String username, ClientGUI cg,ArrayList<ClientThread> al) {
		this.server = server;
		this.port = port;
		this.username = username;
		// save if we are in GUI mode or not
		this.cg = cg;
                this.alist = al;
	}
	
	/*
	 * To start the dialog
	 */
	public boolean start()  {
            
		// try to connect to the server
		try {
			socket = new Socket(server, port);
		} 
		// if it failed not much I can so
		catch(Exception ec) {
			display("Error connectiong to server:" + ec);
			return false;
		}
		String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
		display(msg);
              
		/* Creando ambos Data Stream */
		try
		{
			sInput  = new ObjectInputStream(socket.getInputStream());
			sOutput = new ObjectOutputStream(socket.getOutputStream());
		}
		catch (IOException eIO) {
			display("Exception creating new Input/output Streams: " + eIO);
			return false;
		}

		// creates the Thread to listen from the server 
		new ListenFromServer().start();
		// Send our username to the server this is the only message that we
		// will send as a String. All other messages will be ChatMessage objects
		try
		{
			sOutput.writeObject(username);
		}
		catch (IOException eIO) {
			display("Exception doing login : " + eIO);
			disconnect();
			return false;
		}
		// success we inform the caller that it worked
		return true;
	}

	/*
	 * To send a message to the console or the GUI
	 */
	private void display(String msg) {
		if(cg == null) {
                System.out.println(msg);
            }      // println in console mode
		else {
                cg.append(msg + "\n");
            }		// append to the ClientGUI JTextArea (or whatever)
	}
	
	/*
	 * To send a message to the server
	 */
	void sendMessage(Mensaje msg) {
		try {
			sOutput.writeObject(msg);
		}
		catch(IOException e) {
			display("Exception writing to server: " + e);
		}
	}

	/*
	 * When something goes wrong
	 * Close the Input/Output streams and disconnect not much to do in the catch clause
	 */
	private void disconnect() {
		try { 
			if(sInput != null) {
                        sInput.close();
                    }
		}
		catch(Exception e) {} // not much else I can do
		try {
			if(sOutput != null) {
                        sOutput.close();
                    }
		}
		catch(Exception e) {} // not much else I can do
        try{
			if(socket != null) {
                socket.close();
            }
		}
		catch(Exception e) {} // not much else I can do
		
		// inform the GUI
		if(cg != null) {
                cg.connectionFailed();
            }
			
	}
	
	/*
	 * a class that waits for the message from the server and append them to the JTextArea
	 * if we have a GUI or simply System.out.println() it in console mode
	 */
	class ListenFromServer extends Thread {
            @Override
		public void run() {
			while(true) {
				try {
					String msg = (String) sInput.readObject();
                                       
					// if console mode print the message and add back the prompt
					if(cg == null) {
						System.out.println(msg);
						System.out.print("> ");
					}
					else {
						cg.append(msg);
					}
				}
				catch(IOException e) {
                                   
                                   /*server="192.168.1.106";
                                   port=5431;
                                   username="maria";
                                   new ClientGUI("192.168.1.106",5431);

                                         break;   */
                             
					
                                }
				// can't happen with a String object but need the catch anyhow
				catch(ClassNotFoundException e2) {
				}
			}
		}
        }
}